# Load required packages
library(tidyverse)
library(scales)
library(viridis)
library(knitr)
library(kableExtra)
library(ggridges)
library(patchwork)

# Interactive visualization packages
library(plotly)
library(highcharter)
library(DT)
library(crosstalk)
library(htmltools)

# Set theme for all plots
theme_set(theme_minimal(base_size = 12) +
 theme(
   plot.title = element_text(face = "bold", size = 14),
   plot.subtitle = element_text(color = "gray40"),
   legend.position = "bottom",
   panel.grid.minor = element_blank()
 ))

# Custom color palette for fish families
fish_colors <- c(
 "Gobiidae" = "#1f77b4",
 "Atherinopsidae" = "#ff7f0e",
 "Fundulidae" = "#2ca02c",
 "Paralichthyidae" = "#d62728",
 "Syngnathidae" = "#9467bd",
 "Embiotocidae" = "#8c564b",
 "Cottidae" = "#e377c2",
 "Other" = "#7f7f7f"
)

# Publication-quality Highcharter theme
hc_theme_csm <- hc_theme(
 colors = c("#2171b5", "#cb181d", "#238b45", "#fe9929", "#6a51a3", "#41b6c4"),
 chart = list(
   backgroundColor = "#ffffff",
   style = list(fontFamily = "Helvetica Neue, Arial, sans-serif")
 ),
 title = list(style = list(
   fontWeight = "600",
   fontSize = "16px",
   color = "#1a1a1a"
 )),
 subtitle = list(style = list(
   color = "#666666",
   fontSize = "12px"
 )),
 xAxis = list(
   lineColor = "#333333",
   tickColor = "#333333",
   labels = list(style = list(color = "#333333", fontSize = "11px")),
   title = list(style = list(color = "#333333", fontSize = "12px", fontWeight = "500"))
 ),
 yAxis = list(
   gridLineColor = "#e6e6e6",
   lineColor = "#333333",
   labels = list(style = list(color = "#333333", fontSize = "11px")),
   title = list(style = list(color = "#333333", fontSize = "12px", fontWeight = "500"))
 ),
 legend = list(
   itemStyle = list(color = "#333333", fontSize = "11px"),
   itemHoverStyle = list(color = "#1a1a1a")
 ),
 tooltip = list(
   backgroundColor = "rgba(255,255,255,0.95)",
   borderColor = "#cccccc",
   borderRadius = 4,
   style = list(fontSize = "12px")
 ),
 credits = list(enabled = FALSE)
)

1 Introduction

1.1 The Carpinteria Salt Marsh

# Interactive map using leaflet
library(leaflet)

leaflet() %>%
 addProviderTiles(providers$Esri.WorldImagery) %>%
 setView(lng = -119.538, lat = 34.401, zoom = 14) %>%
 addMarkers(
   lng = -119.538, lat = 34.401,
   popup = "<b>Carpinteria Salt Marsh</b><br>~230 acres of coastal wetland<br>Santa Barbara County, CA"
 ) %>%
 addScaleBar(position = "bottomleft")

Carpinteria Salt Marsh is a ~230-acre coastal wetland located in Santa Barbara County, California. It represents one of the few remaining relatively undisturbed tidal wetlands along the Southern California coast and serves as critical habitat for numerous fish species.

1.1.1 Why Study Salt Marsh Fishes?

Salt marshes provide essential ecosystem services:

  • Nursery habitat for juvenile fishes of commercial and recreational importance
  • Foraging grounds for resident species adapted to fluctuating conditions
  • Refugia from predators in shallow, vegetated waters
  • Productivity hotspots supporting complex food webs

1.1.2 Data Source

This report analyzes data from the SONGS (San Onofre Nuclear Generating Station) Mitigation Monitoring Program collected by UC Santa Barbara’s Marine Science Institute from 2012-2024. The monitoring uses two complementary sampling methods:

  1. Enclosure traps (0.43 m²) - targeting small benthic gobies
  2. Beach seines (~100 m²) - capturing larger mobile fishes

1.2 Learning Objectives

By the end of this report, you should be able to:

  1. Identify the dominant fish species in Carpinteria Salt Marsh
  2. Describe how fish communities differ between tidal creek and main channel habitats
  3. Explain temporal patterns in fish abundance and diversity
  4. Compare sampling methods and understand their biases
  5. Discuss the ecological significance of salt marsh fishes

2 Fish Adaptations & Ecology

Living in a salt marsh presents extreme physiological challenges. Understanding these challenges helps explain why certain fish species thrive here while others cannot survive.

2.1 Environmental Challenges

2.1.1 Life on the Edge

Salt marsh fishes face some of the most demanding conditions in the marine environment:

Temperature Extremes Water temperature can swing 15-32°C (59-90°F) twice daily with tidal cycles. During low tide, shallow pools heat rapidly under the sun, then cool dramatically when oceanic water floods back in. Few marine fishes can tolerate such rapid temperature changes.

Oxygen Depletion Warm water holds less dissolved oxygen than cold water. Combined with the high biological oxygen demand from decomposing organic matter, salt marsh waters frequently become hypoxic (low oxygen), especially at night when photosynthesis stops but respiration continues.

Salinity Fluctuations Tidal mixing creates salinity gradients from nearly fresh (during rain events) to hypersaline (>40 ppt in evaporating pools). Fish must constantly osmoregulate—expending energy to maintain internal salt balance.

Tidal Stranding Twice daily, receding tides can trap fish in isolated pools or expose them to air. Species that cannot find refugia or tolerate brief air exposure are excluded from this habitat.

2.2 Remarkable Adaptations

2.2.1 Goby Specializations

The gobies (Family Gobiidae) that dominate salt marshes possess remarkable adaptations:

Fused Pelvic Fins Goby pelvic fins are fused into a sucking disc that allows them to cling to rocks, mud, and vegetation. This prevents them from being swept away by strong tidal currents and helps them stay in place while foraging.

Air Breathing Several goby species, especially the Longjaw Mudsucker (Gillichthys mirabilis), can survive out of water for extended periods. They accomplish this through a capillary network in the roof of their mouth that allows gas exchange with air—essentially breathing through their mouth lining!

Burrowing Behavior Mudsuckers don’t dig their own burrows—they’re “cheaters” that move into abandoned burrows dug by ghost shrimp and crabs. Males will even suck crabs right out of their burrows to take over the space! These burrows provide refuge from predators and temperature extremes.

2.2.2 Flatfish Transformations

Flatfishes like California Halibut undergo one of the most remarkable transformations in the fish world:

Eye Migration Flatfish larvae start life as normal-looking fish with eyes on both sides of their head. As they develop, one eye physically migrates across the skull to join the other eye on what becomes the “top” side. In halibut, this creates “left-eyed” and “right-eyed” individuals—their “handedness” is determined during development.

Master Camouflage Flatfish can rapidly change their skin color and pattern to match the substrate below them. They achieve near-perfect camouflage by using specialized pigment cells (chromatophores) that expand or contract to create different colors and patterns.

Counter-Shading Like many fishes, flatfish display counter-shading—dark on top (to blend with the bottom when viewed from above) and light on the bottom (to blend with the bright surface when viewed from below). This provides protection throughout the water column.

2.3 Nursery Function

2.3.1 Critical Habitat for Juveniles

Salt marshes serve as essential nursery habitat for many commercially and ecologically important species:

California Halibut (Paralichthys californicus) Juvenile halibut spend their first 1-2 years in shallow estuarine habitats before moving offshore as adults. The marsh provides abundant food (small fishes, shrimp) and protection from larger predators. Without healthy salt marshes, halibut populations would decline.

Leopard Sharks & Round Stingrays Female leopard sharks and round stingrays enter salt marshes specifically to give birth in warm, protected waters. The warm temperatures accelerate embryonic development, and the shallow habitat excludes larger sharks that might prey on newborns.

2.4 Conservation Context

2.4.1 A Vanishing Ecosystem

Only 3% of California’s original coastal wetlands remain intact.

Since European settlement, over 90% of California’s tidal wetlands have been destroyed by: - Agricultural conversion - Urban development - Port and marina construction - Flood control projects

Carpinteria Salt Marsh represents one of the last relatively undisturbed tidal wetlands in Southern California. Its fish community provides a valuable reference for understanding what healthy wetland function looks like—critical information for evaluating restoration projects like the San Dieguito Wetland.

2.4.2 Why Fishes Matter

The fish community serves as an indicator of ecosystem health: - High fish diversity suggests good habitat quality - Presence of nursery species indicates connectivity with the ocean - Resident specialists (gobies) reflect stable, functioning marsh processes - Visiting predators (sharks, rays) indicate adequate prey resources

Long-term monitoring of salt marsh fishes helps scientists detect changes in ecosystem condition and evaluate whether management actions are working.

2.5 Sampling Considerations

2.5.1 What We Catch vs. What’s There

No sampling method captures all fishes equally. Understanding gear biases is essential for interpreting community data:

Beach Seine Limitations - Fast-swimming fishes can outswim the net - Some species jump over the net when cornered - Burrowing fishes (like mudsuckers in their burrows) are missed entirely - Rare or cryptic species may avoid capture

Enclosure Trap Limitations - Only samples small areas (0.43 m²) - Targets benthic gobies; misses pelagic species - Placement affects what’s caught (burrow vs. open mud)

Complementary Methods Scientists increasingly use environmental DNA (eDNA) as a complementary approach. By filtering water samples and extracting DNA, researchers can detect species that avoid traditional sampling gear—providing a more complete picture of the fish community.


3 Data Preparation

# Load the datasets
# Performance standard data (summarized annual estimates)
ps_data <- read_csv("edi.648.8/wetland_ps_fish_abundance_and_richness-2025-08-27_14-22-49.csv")

# Raw enclosure trap data (gobies)
enclosure_data <- read_csv("edi.647.8/wetland_ts_fish_enclosure-2025-08-27_14-40-54.csv")

# Raw beach seine data (larger fishes)
seine_data <- read_csv("edi.647.8/wetland_ts_fish_seine-2025-08-27_14-42-14.csv")
# Filter to Carpinteria Salt Marsh only
csm_ps <- ps_data %>%
 filter(wetland_code == "CSM")

csm_enclosure <- enclosure_data %>%
 filter(wetland_code == "CSM")

csm_seine <- seine_data %>%
 filter(wetland_code == "CSM")
# Quick summary of the CSM dataset
data_summary <- tibble(
 `Data Type` = c("Performance Summary", "Enclosure Traps", "Beach Seines"),
 `Years` = c(
   paste(range(csm_ps$year), collapse = "-"),
   paste(range(csm_enclosure$year), collapse = "-"),
   paste(range(csm_seine$year), collapse = "-")
 ),
 `Total Records` = c(
   nrow(csm_ps),
   nrow(csm_enclosure),
   nrow(csm_seine)
 ),
 `Sampling Locations` = c(
   n_distinct(csm_ps$tc_mc_code),
   n_distinct(csm_enclosure$tc_mc_code),
   n_distinct(csm_seine$tc_mc_code)
 )
)

datatable(data_summary,
         caption = "Summary of Carpinteria Salt Marsh Fish Data",
         options = list(dom = 't', pageLength = 5),
         class = 'cell-border stripe')

4 Fish Community Composition

4.1 Species Inventory

What fish species call Carpinteria Salt Marsh home? Let’s build a comprehensive species list from both sampling methods.

# Get species from enclosure data
enclosure_species <- csm_enclosure %>%
 filter(count > 0) %>%
 distinct(species_code, genus_name, species_name) %>%
 mutate(method = "Enclosure")

# Get species from seine data
seine_species <- csm_seine %>%
 filter(count > 0) %>%
 distinct(species_code, genus_name, species_name) %>%
 mutate(method = "Seine")

# Combine and identify which method caught each species
all_species <- bind_rows(enclosure_species, seine_species) %>%
 group_by(species_code, genus_name, species_name) %>%
 summarize(
   caught_by = paste(unique(method), collapse = " & "),
   .groups = "drop"
 ) %>%
 arrange(genus_name, species_name)

# Add common names from FishBase (comprehensive lookup)
common_names <- tribble(
 ~species_code, ~common_name, ~family,
 # Gobies (Gobiidae)
 "ACFV", "Yellowfin Goby", "Gobiidae",
 "CLIO", "Arrow Goby", "Gobiidae",
 "CTSA", "Longtail Goby", "Gobiidae",
 "GIMI", "Longjaw Mudsucker", "Gobiidae",
 "ILGI", "Cheekspot Goby", "Gobiidae",
 "QUYC", "American Shadow Goby", "Gobiidae",
 # Silversides (Atherinopsidae)
 "ATAF", "Topsmelt Silverside", "Atherinopsidae",
 "ATCA", "Jack Silverside", "Atherinopsidae",
 "LETN", "California Grunion", "Atherinopsidae",
 "MEBE", "Inland Silverside", "Atherinopsidae",
 # Killifishes & Livebearers
 "FUPA", "California Killifish", "Fundulidae",
 "GAAF", "Mosquitofish", "Poeciliidae",
 "POLA", "Sailfin Molly", "Poeciliidae",
 # Anchovies & Herrings (Clupeiformes)
 "ANCO", "Deepbody Anchovy", "Engraulidae",
 "ENMO", "Californian Anchovy", "Engraulidae",
 "CLHA", "Pacific Herring", "Clupeidae",
 "SASA", "Pacific Sardine", "Clupeidae",
 # Flatfishes (Pleuronectiformes)
 "HYGU", "Diamond Turbot", "Pleuronectidae",
 "PACA", "California Flounder", "Paralichthyidae",
 "PLCO", "C-O Sole", "Pleuronectidae",
 "PLRI", "Spotted Turbot", "Pleuronectidae",
 "SYAT", "California Tonguefish", "Cynoglossidae",
 # Pipefishes (Syngnathidae)
 "COAC", "Snubnose Pipefish", "Syngnathidae",
 "SYAU", "Barred Pipefish", "Syngnathidae",
 "SYLE", "Bay Pipefish", "Syngnathidae",
 # Sea Basses (Serranidae)
 "PACL", "Kelp Bass", "Serranidae",
 "PAMA", "Spotted Sand Bass", "Serranidae",
 "PANE", "Barred Sand Bass", "Serranidae",
 # Croakers (Sciaenidae)
 "MEUN", "California Kingcroaker", "Sciaenidae",
 "SEPO", "Queen Croaker", "Sciaenidae",
 "UMRO", "Yellowfin Drum", "Sciaenidae",
 # Blennies (Blenniidae)
 "HYGE", "Bay Blenny", "Blenniidae",
 "HYGI", "Rockpool Blenny", "Blenniidae",
 # Kelpfishes & Clinids (Clinidae)
 "GIME", "Striped Kelpfish", "Clinidae",
 "HERO", "Giant Kelpfish", "Clinidae",
 "NEBL", "Sarcastic Fringehead", "Chaenopsidae",
 "NEUN", "Onespot Fringehead", "Chaenopsidae",
 # Other Bony Fishes
 "MUCE", "Flathead Grey Mullet", "Mugilidae",
 "LEAR", "Pacific Staghorn Sculpin", "Cottidae",
 "CYAG", "Shiner Perch", "Embiotocidae",
 "GINI", "Opaleye", "Kyphosidae",
 "HEAZ", "Zebra-perch Sea Chub", "Kyphosidae",
 "STEX", "Californian Needlefish", "Belonidae",
 "SPAR", "Pacific Barracuda", "Sphyraenidae",
 "SPAN", "Bullseye Puffer", "Tetraodontidae",
 "POMY", "Specklefin Midshipman", "Batrachoididae",
 "SERA", "Grass Rockfish", "Sebastidae",
 "ANDA", "Xantic Sargo", "Haemulidae",
 "XECA", "Californian Salema", "Haemulidae",
 # Sharks (Elasmobranchs)
 "TRSE", "Leopard Shark", "Triakidae",
 "MUCA", "Gray Smoothhound", "Triakidae",
 # Rays (Batoidea)
 "MYCA", "Bat Eagle Ray", "Myliobatidae",
 "URHA", "Haller's Round Ray", "Urotrygonidae",
 "GYMA", "California Butterfly Ray", "Gymnuridae",
 "PLTR", "Thornback Guitarfish", "Platyrhinidae",
 "RHPR", "Shovelnose Guitarfish", "Rhinobatidae"
)

species_table <- all_species %>%
 left_join(common_names, by = "species_code") %>%
 mutate(
   common_name = ifelse(is.na(common_name), "Unknown", common_name),
   family = ifelse(is.na(family), "Other", family)
 ) %>%
 select(common_name, genus_name, species_name, family, caught_by) %>%
 rename(
   `Common Name` = common_name,
   `Genus` = genus_name,
   `Species` = species_name,
   `Family` = family,
   `Sampling Method` = caught_by
 )

n_species <- nrow(species_table)

4.1.1 Total Species Richness: 43 species recorded

# Interactive searchable species table
datatable(species_table,
         caption = "Fish Species Recorded at Carpinteria Salt Marsh (2012-2024) - Click columns to sort, use search box to filter",
         filter = 'top',
         options = list(
           pageLength = 10,
           autoWidth = TRUE,
           columnDefs = list(list(className = 'dt-center', targets = "_all"))
         ),
         class = 'cell-border stripe hover') %>%
 formatStyle('Family',
             backgroundColor = styleEqual(
               c("Gobiidae", "Atherinopsidae", "Fundulidae"),
               c("#e3f2fd", "#fff3e0", "#e8f5e9")
             ))

4.2 Dominant Species

Not all species are equally abundant. Let’s identify the most common fishes.

# Calculate total abundance by species from enclosure data
enclosure_totals <- csm_enclosure %>%
 group_by(species_code, genus_name, species_name) %>%
 summarize(
   total_count = sum(count, na.rm = TRUE),
   n_samples = n_distinct(paste(year, date, tc_mc_code)),
   .groups = "drop"
 ) %>%
 filter(total_count > 0) %>%
 left_join(common_names, by = "species_code") %>%
 mutate(
   common_name = ifelse(is.na(common_name), paste(genus_name, species_name), common_name),
   prop = total_count / sum(total_count)
 ) %>%
 arrange(desc(total_count))
# Calculate total abundance by species from seine data
seine_totals <- csm_seine %>%
 group_by(species_code, genus_name, species_name) %>%
 summarize(
   total_count = sum(count, na.rm = TRUE),
   n_samples = n_distinct(paste(year, date, tc_mc_code)),
   .groups = "drop"
 ) %>%
 filter(total_count > 0) %>%
 left_join(common_names, by = "species_code") %>%
 mutate(
   common_name = ifelse(is.na(common_name), paste(genus_name, species_name), common_name),
   prop = total_count / sum(total_count)
 ) %>%
 arrange(desc(total_count))

4.2.1 Enclosure Trap Catches (Gobies) - Interactive

# Interactive bar chart with Highcharter - Publication Quality
goby_data <- enclosure_totals %>%
 slice_head(n = 5) %>%
 mutate(
   family = ifelse(is.na(family), "Other", family),
   pct = round(prop * 100, 1)
 )

# Professional color palette for gobies
goby_colors <- c("#1f77b4", "#4292c6", "#6baed6", "#9ecae1", "#c6dbef")

highchart() %>%
 hc_chart(type = "bar", backgroundColor = "#ffffff") %>%
 hc_title(
   text = "Goby Species Abundance",
   style = list(fontSize = "16px", fontWeight = "600")
 ) %>%
 hc_subtitle(
   text = "Enclosure trap sampling, Carpinteria Salt Marsh (2012–2024)",
   style = list(fontSize = "12px", color = "#666666")
 ) %>%
 hc_xAxis(
   categories = goby_data$common_name,
   labels = list(style = list(fontSize = "12px", fontWeight = "500")),
   lineWidth = 0
 ) %>%
 hc_yAxis(
   title = list(text = "Total Individuals Captured", style = list(fontSize = "12px")),
   labels = list(format = "{value:,.0f}"),
   gridLineColor = "#e6e6e6"
 ) %>%
 hc_add_series(
   name = "Count",
   data = goby_data$total_count,
   colorByPoint = TRUE,
   colors = goby_colors
 ) %>%
 hc_tooltip(
   pointFormat = "<b>{point.category}</b><br>Total: <b>{point.y:,.0f}</b> individuals",
   headerFormat = "",
   backgroundColor = "rgba(255,255,255,0.95)",
   borderColor = "#cccccc"
 ) %>%
 hc_plotOptions(
   bar = list(
     borderRadius = 3,
     dataLabels = list(
       enabled = TRUE,
       format = "{point.y:,.0f}",
       style = list(fontSize = "11px", fontWeight = "500", textOutline = "none")
     )
   )
 ) %>%
 hc_legend(enabled = FALSE) %>%
 hc_credits(enabled = FALSE)

Key Finding: The Arrow Goby (Clevelandia ios) is by far the most abundant fish in the salt marsh, followed by the Cheekspot Goby and Shadow Goby. These small gobies are specialists of soft-bottom estuarine habitats.

4.2.2 Beach Seine Catches (Larger Fishes) - Interactive

# Interactive treemap showing species composition - Publication Quality
seine_top <- seine_totals %>%
 slice_head(n = 12) %>%
 mutate(family = ifelse(is.na(family), "Other", family))

highchart() %>%
 hc_chart(type = "treemap", backgroundColor = "#ffffff") %>%
 hc_title(
   text = "Seine Catch Composition by Species",
   style = list(fontSize = "16px", fontWeight = "600")
 ) %>%
 hc_subtitle(
   text = "Area proportional to total abundance (2012–2024)",
   style = list(fontSize = "12px", color = "#666666")
 ) %>%
 hc_add_series(
   data = list_parse(
     seine_top %>%
       transmute(
         name = common_name,
         value = total_count,
         colorValue = log10(total_count + 1)
       )
   ),
   layoutAlgorithm = "squarified",
   borderColor = "#ffffff",
   borderWidth = 2
 ) %>%
 hc_colorAxis(
   minColor = "#deebf7",
   maxColor = "#08519c",
   type = "linear"
 ) %>%
 hc_tooltip(
   pointFormat = "<b>{point.name}</b><br>Total: <b>{point.value:,.0f}</b> individuals",
   backgroundColor = "rgba(255,255,255,0.95)",
   borderColor = "#cccccc"
 ) %>%
 hc_plotOptions(
   treemap = list(
     dataLabels = list(
       enabled = TRUE,
       style = list(fontSize = "11px", fontWeight = "500", textOutline = "none", color = "#ffffff")
     )
   )
 ) %>%
 hc_credits(enabled = FALSE)

Key Finding: Topsmelt (Atherinops affinis) and California Killifish (Fundulus parvipinnis) dominate seine catches. Both species are highly adapted to estuarine conditions with fluctuating salinity and temperature.


5 Habitat Comparisons

Salt marshes contain diverse microhabitats. At Carpinteria, sampling occurs in two distinct habitat types:

  • Tidal Creeks (TC): Narrow, shallow channels that drain the marsh plain
  • Main Channels/Basins (BNMC): Deeper, more permanent waterways
# Summarize by habitat
habitat_summary <- csm_ps %>%
 mutate(habitat = ifelse(habitat_code == "TC", "Tidal Creek", "Main Channel")) %>%
 group_by(year, habitat) %>%
 summarize(
   mean_density = mean(count_per_m2, na.rm = TRUE),
   se_density = sd(count_per_m2, na.rm = TRUE) / sqrt(n()),
   mean_richness = mean(species_count, na.rm = TRUE),
   se_richness = sd(species_count, na.rm = TRUE) / sqrt(n()),
   n = n(),
   .groups = "drop"
 )

5.1 Fish Density by Habitat - Interactive

# Interactive time series with Plotly - Publication Quality
p_density <- habitat_summary %>%
 ggplot(aes(x = year, y = mean_density, color = habitat,
            text = paste0("Year: ", year,
                         "<br>Habitat: ", habitat,
                         "<br>Mean Density: ", round(mean_density, 2), " fish/m²",
                         "<br>SE: ±", round(se_density, 2)))) +
 geom_ribbon(aes(ymin = mean_density - se_density,
                 ymax = mean_density + se_density,
                 fill = habitat),
             alpha = 0.15, color = NA) +
 geom_line(linewidth = 1.2) +
 geom_point(size = 3) +
 scale_color_manual(values = c("Main Channel" = "#2171b5", "Tidal Creek" = "#cb181d")) +
 scale_fill_manual(values = c("Main Channel" = "#2171b5", "Tidal Creek" = "#cb181d")) +
 scale_x_continuous(breaks = seq(2012, 2024, 2)) +
 scale_y_continuous(limits = c(0, NA), expand = expansion(mult = c(0, 0.05))) +
 labs(
   title = "Fish Density by Habitat Type",
   subtitle = "Mean ± SE, Carpinteria Salt Marsh (2012–2024)",
   x = "Year",
   y = expression(paste("Fish Density (individuals/m"^2, ")")),
   color = "Habitat",
   fill = "Habitat"
 ) +
 theme_minimal(base_size = 12) +
 theme(
   legend.position = "top",
   legend.title = element_text(face = "bold", size = 10),
   plot.title = element_text(face = "bold", size = 14),
   plot.subtitle = element_text(color = "gray40", size = 11),
   axis.title = element_text(size = 11),
   axis.text = element_text(size = 10),
   panel.grid.minor = element_blank(),
   panel.grid.major = element_line(color = "#e6e6e6")
 )

ggplotly(p_density, tooltip = "text") %>%
 layout(
   hoverlabel = list(bgcolor = "white", font = list(size = 12)),
   legend = list(orientation = "h", y = 1.1, x = 0.5, xanchor = "center")
 )

5.2 Species Richness by Habitat - Interactive

# Highcharter line chart - Publication Quality
highchart() %>%
 hc_chart(type = "line", backgroundColor = "#ffffff") %>%
 hc_title(
   text = "Species Richness by Habitat Type",
   style = list(fontSize = "16px", fontWeight = "600")
 ) %>%
 hc_subtitle(
   text = "Mean number of species per sample (2012–2024)",
   style = list(fontSize = "12px", color = "#666666")
 ) %>%
 hc_xAxis(
   categories = unique(habitat_summary$year),
   labels = list(style = list(fontSize = "11px")),
   lineColor = "#333333"
 ) %>%
 hc_yAxis(
   title = list(text = "Mean Species Richness", style = list(fontSize = "12px")),
   labels = list(format = "{value:.0f}"),
   gridLineColor = "#e6e6e6",
   min = 0
 ) %>%
 hc_add_series(
   name = "Tidal Creek",
   data = habitat_summary %>% filter(habitat == "Tidal Creek") %>% arrange(year) %>% pull(mean_richness),
   color = "#cb181d",
   lineWidth = 2
 ) %>%
 hc_add_series(
   name = "Main Channel",
   data = habitat_summary %>% filter(habitat == "Main Channel") %>% arrange(year) %>% pull(mean_richness),
   color = "#2171b5",
   lineWidth = 2
 ) %>%
 hc_tooltip(
   shared = TRUE,
   crosshairs = TRUE,
   pointFormat = "{series.name}: <b>{point.y:.1f}</b> species<br>",
   backgroundColor = "rgba(255,255,255,0.95)",
   borderColor = "#cccccc"
 ) %>%
 hc_plotOptions(
   line = list(
     marker = list(enabled = TRUE, radius = 4, symbol = "circle")
   )
 ) %>%
 hc_legend(
   align = "center",
   verticalAlign = "bottom",
   itemStyle = list(fontSize = "11px")
 ) %>%
 hc_credits(enabled = FALSE)

5.2.1 Habitat Comparison Summary

habitat_overall <- csm_ps %>%
 mutate(habitat = ifelse(habitat_code == "TC", "Tidal Creek", "Main Channel")) %>%
 group_by(habitat) %>%
 summarize(
   `Mean Density (fish/m²)` = round(mean(count_per_m2, na.rm = TRUE), 2),
   `SD Density` = round(sd(count_per_m2, na.rm = TRUE), 2),
   `Max Density` = round(max(count_per_m2, na.rm = TRUE), 2),
   `Mean Richness` = round(mean(species_count, na.rm = TRUE), 1),
   `Max Richness` = max(species_count, na.rm = TRUE),
   `N Samples` = n(),
   .groups = "drop"
 )

datatable(habitat_overall,
         caption = "Summary Statistics by Habitat Type (2012-2024)",
         options = list(dom = 't'),
         class = 'cell-border stripe') %>%
 formatStyle(
   'Mean Density (fish/m²)',
   background = styleColorBar(c(0, max(habitat_overall$`Mean Density (fish/m²)`)), '#3498db'),
   backgroundSize = '98% 88%',
   backgroundRepeat = 'no-repeat',
   backgroundPosition = 'center'
 )

Discussion Question: Why might tidal creeks have higher fish densities but similar or lower species richness compared to main channels?


6 Temporal Patterns

6.1 Interannual Variation - Interactive Explorer

Fish populations in estuaries can vary dramatically from year to year due to environmental conditions, recruitment variability, and other factors.

annual_summary <- csm_ps %>%
 group_by(year) %>%
 summarize(
   total_density = sum(count_per_m2, na.rm = TRUE),
   mean_density = mean(count_per_m2, na.rm = TRUE),
   se_density = sd(count_per_m2, na.rm = TRUE) / sqrt(n()),
   mean_richness = mean(species_count, na.rm = TRUE),
   se_richness = sd(species_count, na.rm = TRUE) / sqrt(n()),
   n_locations = n(),
   .groups = "drop"
 )
# Interactive combined chart - Publication Quality
highchart() %>%
 hc_chart(zoomType = "x", backgroundColor = "#ffffff") %>%
 hc_title(
   text = "Long-term Trends in Fish Community",
   style = list(fontSize = "16px", fontWeight = "600")
 ) %>%
 hc_subtitle(
   text = "Carpinteria Salt Marsh (2012–2024)",
   style = list(fontSize = "12px", color = "#666666")
 ) %>%
 hc_xAxis(
   categories = annual_summary$year,
   labels = list(style = list(fontSize = "11px")),
   lineColor = "#333333"
 ) %>%
 hc_yAxis_multiples(
   list(
     title = list(
       text = "Mean Density (fish/m²)",
       style = list(color = "#2171b5", fontSize = "12px")
     ),
     labels = list(style = list(color = "#2171b5", fontSize = "11px"), format = "{value:.1f}"),
     gridLineColor = "#e6e6e6",
     min = 0
   ),
   list(
     title = list(
       text = "Mean Species Richness",
       style = list(color = "#cb181d", fontSize = "12px")
     ),
     labels = list(style = list(color = "#cb181d", fontSize = "11px"), format = "{value:.0f}"),
     opposite = TRUE,
     min = 0
   )
 ) %>%
 hc_add_series(
   name = "Fish Density",
   data = round(annual_summary$mean_density, 2),
   type = "column",
   color = "#2171b5",
   yAxis = 0,
   borderRadius = 2
 ) %>%
 hc_add_series(
   name = "Species Richness",
   data = round(annual_summary$mean_richness, 1),
   type = "spline",
   color = "#cb181d",
   yAxis = 1,
   lineWidth = 2,
   marker = list(radius = 4, symbol = "circle")
 ) %>%
 hc_tooltip(
   shared = TRUE,
   crosshairs = TRUE,
   backgroundColor = "rgba(255,255,255,0.95)",
   borderColor = "#cccccc"
 ) %>%
 hc_legend(
   align = "center",
   verticalAlign = "bottom",
   itemStyle = list(fontSize = "11px")
 ) %>%
 hc_credits(enabled = FALSE)

6.2 Distribution of Fish Densities - Interactive Boxplots

# Interactive boxplots by year - Publication Quality
# Use a sequential blue palette
year_colors <- colorRampPalette(c("#c6dbef", "#08519c"))(13)

csm_ps %>%
 plot_ly(x = ~factor(year), y = ~count_per_m2, type = "box",
         color = ~factor(year), colors = year_colors,
         hoverinfo = "y",
         marker = list(outliercolor = "#333333", size = 4),
         line = list(color = "#333333", width = 1)) %>%
 layout(
   title = list(
     text = "Distribution of Fish Densities by Year",
     font = list(size = 16, family = "Helvetica Neue, Arial", color = "#1a1a1a")
   ),
   xaxis = list(
     title = list(text = "Year", font = list(size = 12)),
     tickfont = list(size = 11)
   ),
   yaxis = list(
     title = list(text = "Fish Density (individuals/m²)", font = list(size = 12)),
     tickfont = list(size = 11),
     gridcolor = "#e6e6e6",
     rangemode = "tozero"
   ),
   showlegend = FALSE,
   plot_bgcolor = "#ffffff",
   paper_bgcolor = "#ffffff"
 )

6.3 All Sampling Locations - Scatter Explorer

# Create linked dataset with crosstalk - Publication Quality
csm_shared <- SharedData$new(
 csm_ps %>%
   mutate(
     habitat = ifelse(habitat_code == "TC", "Tidal Creek", "Main Channel"),
     location = tc_mc_code
   )
)

# Interactive scatter with crosstalk filtering
bscols(
 widths = c(3, 9),
 list(
   filter_checkbox("habitat", "Habitat", csm_shared, ~habitat),
   filter_slider("year", "Year", csm_shared, ~year, step = 1, width = "100%"),
   filter_slider("density", "Density", csm_shared, ~count_per_m2, width = "100%")
 ),
 plot_ly(csm_shared, x = ~species_count, y = ~count_per_m2,
         color = ~habitat, colors = c("#2171b5", "#cb181d"),
         text = ~paste0("Location: ", location,
                       "<br>Year: ", year,
                       "<br>Density: ", round(count_per_m2, 2), " fish/m²",
                       "<br>Species: ", species_count),
         hoverinfo = "text",
         type = "scatter", mode = "markers",
         marker = list(size = 10, opacity = 0.7, line = list(color = "#ffffff", width = 1))) %>%
   layout(
     title = list(
       text = "Density vs Species Richness",
       font = list(size = 16, family = "Helvetica Neue, Arial", color = "#1a1a1a")
     ),
     xaxis = list(
       title = list(text = "Number of Species", font = list(size = 12)),
       tickfont = list(size = 11),
       gridcolor = "#e6e6e6"
     ),
     yaxis = list(
       title = list(text = "Fish Density (individuals/m²)", font = list(size = 12)),
       tickfont = list(size = 11),
       gridcolor = "#e6e6e6",
       rangemode = "tozero"
     ),
     legend = list(
       orientation = "h", y = -0.15, x = 0.5, xanchor = "center",
       font = list(size = 11)
     ),
     plot_bgcolor = "#ffffff",
     paper_bgcolor = "#ffffff"
   )
)

6.4 Notable Years

# Find the highest and lowest years
peak_year <- annual_summary %>% slice_max(mean_density, n = 1)
low_year <- annual_summary %>% slice_min(mean_density, n = 1)
  • Highest Density Year: 2015 with mean 56.7 fish/m²
  • Lowest Density Year: 2012 with mean 3.2 fish/m²

Question for Discussion: What environmental factors might explain this variation? Consider: El Niño events, drought conditions, marine heatwaves, and local management changes.


8 Species Profiles

Let’s take a closer look at some key species found in Carpinteria Salt Marsh.

8.1 Arrow Goby (Clevelandia ios)

arrow_goby <- csm_enclosure %>%
 filter(species_code == "CLIO") %>%
 group_by(year, habitat_code) %>%
 summarize(
   total_count = sum(count, na.rm = TRUE),
   mean_count = mean(count, na.rm = TRUE),
   .groups = "drop"
 )

8.1.1 Biology

The Arrow Goby is a small (< 5 cm) benthic fish endemic to the Pacific coast of North America. Key traits include: - Habitat: Soft mud bottoms, often associated with ghost shrimp burrows - Diet: Small invertebrates, detritus - Reproduction: Males guard eggs in burrow chambers - Ecological Role: Important prey for larger fishes and wading birds

8.1.2 Abundance Over Time

# Arrow Goby stacked chart - Publication Quality
arrow_goby_wide <- arrow_goby %>%
 mutate(habitat = ifelse(habitat_code == "TC", "Tidal Creek", "Main Channel")) %>%
 pivot_wider(names_from = habitat, values_from = c(total_count, mean_count), values_fill = 0)

highchart() %>%
 hc_chart(type = "column", backgroundColor = "#ffffff") %>%
 hc_title(
   text = "Arrow Goby Annual Abundance",
   style = list(fontSize = "16px", fontWeight = "600")
 ) %>%
 hc_subtitle(
   text = "Total count by habitat (2012–2024)",
   style = list(fontSize = "12px", color = "#666666")
 ) %>%
 hc_xAxis(
   categories = unique(arrow_goby$year),
   labels = list(style = list(fontSize = "11px"))
 ) %>%
 hc_yAxis(
   title = list(text = "Total Individuals", style = list(fontSize = "12px")),
   labels = list(format = "{value:,.0f}"),
   gridLineColor = "#e6e6e6",
   stackLabels = list(enabled = FALSE)
 ) %>%
 hc_plotOptions(column = list(stacking = "normal", borderRadius = 2)) %>%
 hc_add_series(
   name = "Tidal Creek",
   data = arrow_goby %>% filter(habitat_code == "TC") %>% arrange(year) %>% pull(total_count),
   color = "#cb181d"
 ) %>%
 hc_add_series(
   name = "Main Channel",
   data = arrow_goby %>% filter(habitat_code == "BNMC") %>% arrange(year) %>% pull(total_count),
   color = "#2171b5"
 ) %>%
 hc_tooltip(
   shared = TRUE,
   pointFormat = "{series.name}: <b>{point.y:,.0f}</b><br>",
   backgroundColor = "rgba(255,255,255,0.95)",
   borderColor = "#cccccc"
 ) %>%
 hc_legend(
   align = "center",
   verticalAlign = "bottom",
   itemStyle = list(fontSize = "11px")
 ) %>%
 hc_credits(enabled = FALSE)

8.2 California Killifish (Fundulus parvipinnis)

killifish <- csm_seine %>%
 filter(species_code == "FUPA") %>%
 group_by(year, habitat_code) %>%
 summarize(
   total_count = sum(count, na.rm = TRUE),
   .groups = "drop"
 )

The California Killifish is a euryhaline species (tolerant of wide salinity ranges) that is endemic to California and Baja California estuaries.

  • Size: Up to 11 cm
  • Diet: Invertebrates, algae, detritus
  • Special Adaptation: Can tolerate salinities from fresh water to >100 ppt
  • Behavior: Forms schools in shallow areas
# California Killifish grouped bar chart - Publication Quality
killifish %>%
 mutate(habitat = ifelse(habitat_code == "TC", "Tidal Creek", "Main Channel")) %>%
 plot_ly(x = ~year, y = ~total_count, color = ~habitat,
         colors = c("#2171b5", "#cb181d"),
         type = "bar",
         hoverinfo = "text",
         text = ~paste0("Year: ", year, "<br>",
                       "Habitat: ", habitat, "<br>",
                       "Count: ", comma(total_count))) %>%
 layout(
   title = list(
     text = "California Killifish Annual Abundance",
     font = list(size = 16, family = "Helvetica Neue, Arial", color = "#1a1a1a")
   ),
   barmode = "group",
   xaxis = list(
     title = list(text = "Year", font = list(size = 12)),
     tickfont = list(size = 11)
   ),
   yaxis = list(
     title = list(text = "Total Individuals", font = list(size = 12)),
     tickfont = list(size = 11),
     gridcolor = "#e6e6e6",
     rangemode = "tozero"
   ),
   legend = list(
     orientation = "h", y = -0.15, x = 0.5, xanchor = "center",
     font = list(size = 11)
   ),
   plot_bgcolor = "#ffffff",
   paper_bgcolor = "#ffffff"
 )

8.3 Topsmelt (Atherinops affinis)

topsmelt <- csm_seine %>%
 filter(species_code == "ATAF") %>%
 group_by(year) %>%
 summarize(
   total_count = sum(count, na.rm = TRUE),
   .groups = "drop"
 )

Topsmelt are schooling silversides that are abundant in California bays and estuaries.

  • Size: Up to 37 cm (commonly 15-25 cm)
  • Diet: Zooplankton, small invertebrates, algae
  • Reproduction: Spawns in eelgrass and algae beds
  • Fishery: Important forage fish for seabirds and larger predators
# Topsmelt area chart - Publication Quality
highchart() %>%
 hc_chart(type = "areaspline", backgroundColor = "#ffffff") %>%
 hc_title(
   text = "Topsmelt Annual Abundance",
   style = list(fontSize = "16px", fontWeight = "600")
 ) %>%
 hc_subtitle(
   text = "Note the extreme interannual variability",
   style = list(fontSize = "12px", color = "#666666")
 ) %>%
 hc_xAxis(
   categories = topsmelt$year,
   labels = list(style = list(fontSize = "11px"))
 ) %>%
 hc_yAxis(
   title = list(text = "Total Individuals", style = list(fontSize = "12px")),
   labels = list(format = "{value:,.0f}"),
   gridLineColor = "#e6e6e6",
   min = 0
 ) %>%
 hc_add_series(
   name = "Topsmelt",
   data = topsmelt$total_count,
   color = "#fe9929",
   fillColor = list(
     linearGradient = list(x1 = 0, y1 = 0, x2 = 0, y2 = 1),
     stops = list(c(0, "rgba(254,153,41,0.5)"), c(1, "rgba(254,153,41,0.05)"))
   ),
   lineWidth = 2,
   marker = list(radius = 4, symbol = "circle")
 ) %>%
 hc_tooltip(
   pointFormat = "Year {point.category}: <b>{point.y:,.0f}</b> individuals",
   backgroundColor = "rgba(255,255,255,0.95)",
   borderColor = "#cccccc"
 ) %>%
 hc_legend(enabled = FALSE) %>%
 hc_credits(enabled = FALSE)

9 Ecological Guilds

Fish species can be grouped into ecological guilds based on their habitat use and life history strategies.

# Assign guilds to key species
guild_assignments <- tribble(
 ~species_code, ~guild, ~description,
 "CLIO", "Resident", "Spends entire life in estuary",
 "ILGI", "Resident", "Spends entire life in estuary",
 "QUYC", "Resident", "Spends entire life in estuary",
 "GIMI", "Resident", "Spends entire life in estuary",
 "FUPA", "Resident", "Spends entire life in estuary",
 "ATAF", "Marine Migrant", "Uses estuary seasonally",
 "PACA", "Marine Migrant", "Juvenile nursery habitat",
 "HYGU", "Marine Migrant", "Juvenile nursery habitat",
 "SYLE", "Resident", "Spends entire life in estuary",
 "MUCE", "Marine Migrant", "Adults enter to feed",
 "MYCA", "Marine Migrant", "Foraging habitat",
 "ANCO", "Marine Migrant", "Uses estuary seasonally"
)

# Calculate proportions by guild from seine data
guild_summary <- csm_seine %>%
 left_join(guild_assignments, by = "species_code") %>%
 filter(!is.na(guild)) %>%
 group_by(year, guild) %>%
 summarize(total_count = sum(count, na.rm = TRUE), .groups = "drop") %>%
 group_by(year) %>%
 mutate(proportion = total_count / sum(total_count) * 100)
# Ecological guild stacked area chart - Publication Quality
highchart() %>%
 hc_chart(type = "area", backgroundColor = "#ffffff") %>%
 hc_title(
   text = "Ecological Guild Composition",
   style = list(fontSize = "16px", fontWeight = "600")
 ) %>%
 hc_subtitle(
   text = "Proportion of resident vs marine migrant species (2012–2024)",
   style = list(fontSize = "12px", color = "#666666")
 ) %>%
 hc_xAxis(
   categories = unique(guild_summary$year),
   labels = list(style = list(fontSize = "11px"))
 ) %>%
 hc_yAxis(
   title = list(text = "Proportion of Catch", style = list(fontSize = "12px")),
   max = 100,
   labels = list(format = "{value}%", style = list(fontSize = "11px")),
   gridLineColor = "#e6e6e6"
 ) %>%
 hc_plotOptions(
   area = list(
     stacking = "percent",
     lineWidth = 1,
     marker = list(enabled = FALSE)
   )
 ) %>%
 hc_add_series(
   name = "Resident",
   data = guild_summary %>% filter(guild == "Resident") %>% arrange(year) %>% pull(total_count),
   color = "#238b45",
   fillOpacity = 0.7
 ) %>%
 hc_add_series(
   name = "Marine Migrant",
   data = guild_summary %>% filter(guild == "Marine Migrant") %>% arrange(year) %>% pull(total_count),
   color = "#2171b5",
   fillOpacity = 0.7
 ) %>%
 hc_tooltip(
   shared = TRUE,
   pointFormat = "{series.name}: <b>{point.percentage:.1f}%</b> ({point.y:,.0f})<br>",
   backgroundColor = "rgba(255,255,255,0.95)",
   borderColor = "#cccccc"
 ) %>%
 hc_legend(
   align = "center",
   verticalAlign = "bottom",
   itemStyle = list(fontSize = "11px")
 ) %>%
 hc_credits(enabled = FALSE)

10 Summary Statistics

10.1 Overall Community Summary

overall_stats <- csm_ps %>%
 summarize(
   `Years of Data` = paste(min(year), "-", max(year)),
   `Total Sampling Events` = n(),
   `Mean Density (fish/m²)` = round(mean(count_per_m2), 2),
   `Max Density (fish/m²)` = round(max(count_per_m2), 2),
   `Mean Species Richness` = round(mean(species_count), 1),
   `Max Species Richness` = max(species_count)
 )

# Create nice summary cards with HTML
div(class = "row",
   div(class = "col-md-4",
       div(class = "panel panel-primary",
           div(class = "panel-heading", "Years of Monitoring"),
           div(class = "panel-body", style = "font-size: 24px; text-align: center;",
               overall_stats$`Years of Data`))),
   div(class = "col-md-4",
       div(class = "panel panel-success",
           div(class = "panel-heading", "Mean Fish Density"),
           div(class = "panel-body", style = "font-size: 24px; text-align: center;",
               paste(overall_stats$`Mean Density (fish/m²)`, "fish/m²")))),
   div(class = "col-md-4",
       div(class = "panel panel-info",
           div(class = "panel-heading", "Mean Species Richness"),
           div(class = "panel-body", style = "font-size: 24px; text-align: center;",
               paste(overall_stats$`Mean Species Richness`, "species"))))
)
Years of Monitoring
2012 - 2024
Mean Fish Density
24.27 fish/m²
Mean Species Richness
8.6 species

10.2 Species Summary by Abundance Category

# Categorize species by abundance
all_species_counts <- bind_rows(
 csm_enclosure %>%
   group_by(species_code) %>%
   summarize(total = sum(count), .groups = "drop"),
 csm_seine %>%
   group_by(species_code) %>%
   summarize(total = sum(count), .groups = "drop")
) %>%
 group_by(species_code) %>%
 summarize(total = sum(total), .groups = "drop") %>%
 left_join(common_names, by = "species_code") %>%
 mutate(
   category = case_when(
     total > 10000 ~ "Dominant (>10,000)",
     total > 1000 ~ "Common (1,000-10,000)",
     total > 100 ~ "Moderate (100-1,000)",
     total > 10 ~ "Uncommon (10-100)",
     TRUE ~ "Rare (<10)"
   )
 )

category_summary <- all_species_counts %>%
 group_by(category) %>%
 summarize(
   `Number of Species` = n(),
   `Total Individuals` = sum(total),
   .groups = "drop"
 ) %>%
 arrange(desc(`Total Individuals`))

# Pie chart of abundance categories - Publication Quality
# Define custom colors for categories
category_colors <- c(
  "Dominant (>10,000)" = "#08519c",
  "Common (1,000-10,000)" = "#3182bd",
  "Moderate (100-1,000)" = "#6baed6",
  "Uncommon (10-100)" = "#9ecae1",
  "Rare (<10)" = "#c6dbef"
)

highchart() %>%
 hc_chart(type = "pie", backgroundColor = "#ffffff") %>%
 hc_title(
   text = "Species Distribution by Abundance",
   style = list(fontSize = "16px", fontWeight = "600")
 ) %>%
 hc_subtitle(
   text = "Number of species in each abundance category",
   style = list(fontSize = "12px", color = "#666666")
 ) %>%
 hc_add_series(
   name = "Species",
   data = list_parse(
     category_summary %>%
       transmute(
         name = category,
         y = `Number of Species`,
         individuals = `Total Individuals`,
         color = category_colors[category]
       )
   ),
   innerSize = "40%"
 ) %>%
 hc_tooltip(
   pointFormat = "<b>{point.name}</b><br>Species count: <b>{point.y}</b><br>Total individuals: <b>{point.individuals:,.0f}</b>",
   backgroundColor = "rgba(255,255,255,0.95)",
   borderColor = "#cccccc"
 ) %>%
 hc_plotOptions(
   pie = list(
     allowPointSelect = TRUE,
     cursor = "pointer",
     dataLabels = list(
       enabled = TRUE,
       format = "{point.name}: {point.y}",
       style = list(fontSize = "11px", fontWeight = "500", textOutline = "none")
     ),
     showInLegend = FALSE
   )
 ) %>%
 hc_credits(enabled = FALSE)

11 Key Takeaways

11.1 What We’ve Learned About Carpinteria Salt Marsh Fishes

  1. High Diversity: At least 43 fish species use Carpinteria Salt Marsh, from tiny gobies to large elasmobranchs

  2. Goby Dominance: Small benthic gobies, especially the Arrow Goby, numerically dominate the fish community

  3. Habitat Partitioning: Tidal creeks and main channels support different fish densities and compositions

  4. Temporal Variability: Fish populations fluctuate dramatically between years, likely driven by environmental conditions and recruitment

  5. Estuarine Specialists: The community is dominated by resident species highly adapted to fluctuating estuarine conditions

11.2 Discussion Questions

  1. Why are gobies so abundant in salt marshes compared to other habitats?

  2. How might climate change affect salt marsh fish communities?

  3. What is the value of long-term monitoring datasets like this one?

  4. How do sampling methods influence our perception of community composition?


12 References & Further Reading

  • Allen, L.G., M.H. Horn, F.A. Edmands II, and C.A. Usui. 1983. Structure and seasonal dynamics of the fish assemblage in the Cabrillo Beach area of Los Angeles Harbor, California. Bulletin of the Southern California Academy of Sciences 82:47-70.

  • Horn, M.H., and L.G. Allen. 1985. Fish community ecology in southern California bays and estuaries. Pages 169-190 in A. Yanez-Arancibia, editor. Fish community ecology in estuaries and coastal lagoons: Towards ecosystem integration. UNAM Press, Mexico City.

  • Steele, M.A., S.C. Schroeter, and H.M. Page. 2006. Sampling characteristics and biases of enclosure traps for sampling fishes in estuaries. Estuaries and Coasts 29:630-638.

  • SONGS Mitigation Monitoring Program: http://marinemitigation.msi.ucsb.edu/


Report generated on 2025-12-01 using R version R version 4.5.1 (2025-06-13)